
/**
 * tinyurlapi.cpp
 * 
 * TinyUrlAPI is a wrapper of tinyurl API
 * 
 * Copyright (c) 2008 Harunobu Oyama <nobukichi at gmail.com>
 * Licensed under GNU GPL version 3
 *
 */

#include <QtNetwork>
#include <QtXml> 
#include "settingsdialog.h"
#include "usersettings.h"
#include "tinyurlapi.h"

const char* const TINY_URL_HOST = "tinyurl.com";
const char* const ENCODE_API = "/api-create.php?url=";

TinyUrlAPI::TinyUrlAPI(QObject* parent)
  : QObject(parent)
{
	http.setHost(TINY_URL_HOST);
	
	connect( &http, SIGNAL(requestFinished(int, bool)), 
	         this, SLOT(slotRequestFinished(int, bool)) );
}

TinyUrlAPI::~TinyUrlAPI()
{
	reset();
}

void TinyUrlAPI::reset()
{
	http.abort();
}

void TinyUrlAPI::requestEncode(const QString& orgUrl)
{
	QString path = QString(ENCODE_API) + orgUrl;
	sendGetRequest(path, Request::REQ_TYPE_ENCODE, orgUrl);
}

void TinyUrlAPI::requestDecode(const QString& tinyUrl)
{
	DecodeCache::iterator it = decodeCache.find(tinyUrl);
	if (it != decodeCache.end()) {
		emit signalDecodeFinished(tinyUrl, it->second);
		return;
	}

	QString tinyUrlHeader = QString("http://") + TINY_URL_HOST;
	if (tinyUrl.startsWith(tinyUrlHeader)) {
		sendGetRequest(tinyUrl.mid(tinyUrlHeader.size()), Request::REQ_TYPE_DECODE, tinyUrl);
	}
}

void TinyUrlAPI::sendGetRequest(const QString& path, TinyUrlAPI::Request::Type reqType, const QString& extra)
{
	Request request(reqType, extra);
	int requestId = http.get(path, request.responseBuffer());
	activeRequests[requestId] = request;
}

void TinyUrlAPI::slotRequestFinished(int id, bool error)
{
	if (error) {
		emit signalDetectedHttpError(http.error());
	} else {
		RequestMap::iterator it = activeRequests.find(id);
		if (it != activeRequests.end()) {
			switch (it->second.type()) {
			case Request::REQ_TYPE_ENCODE:
				{
					QString orgUrl = it->second.extraInfo();
					QByteArray body = it->second.responseBuffer()->data();
					QString tinyUrl = QString::fromAscii(body.data(), body.size());
					emit signalEncodeFinished(orgUrl, tinyUrl);
				}
				break;
			case Request::REQ_TYPE_DECODE:
				{
					QHttpResponseHeader header = http.lastResponse();
					if (header.statusCode() == 301) {
						QString orgUrl = header.value("Location");
						QString tinyUrl = it->second.extraInfo();
						decodeCache[tinyUrl] = orgUrl;
						emit signalDecodeFinished(tinyUrl, orgUrl);
					}
				}
				break;
			default:
				break;
			}
		}
	}

	activeRequests.erase(id);
}

TinyUrlAPI::Request::Request(TinyUrlAPI::Request::Type type, const QString& info)
  : reqType(type), extra(info), ptrResponseBuffer(new QBuffer())
{
}

TinyUrlAPI::Request::Type TinyUrlAPI::Request::type() const
{
	return reqType;
}

QBuffer* TinyUrlAPI::Request::responseBuffer()
{
	return ptrResponseBuffer.get();
}

QString TinyUrlAPI::Request::extraInfo() const
{
	return extra;
}

